#include "lylog.h"
#include <unistd.h>

void test_basic()
{
    auto logger = ly::LocalBuilder()
                      .buildName("test_logger")
                      .buildSink<ly::StdoutSink>()
                      .build();
    logger->debug("%s\n", "基础框架功能测试");
}

void test_fileSink()
{
    auto logger = ly::LocalBuilder()
                      .buildName("test_logger")
                      .buildSink<ly::FileSink>("test_a.log")
                      .buildSink<ly::FileSink>("./test_b.log")
                      .buildSink<ly::FileSink>("./test_c//test_c.log")
                      .buildSink<ly::FileSink>(".//test_dd///test_d///")
                      .build();
    logger->debug("%s\n", "文件输出器测试");
}

void test_sizeRollSink()
{
    auto logger = ly::LocalBuilder()
                      .buildName("test_logger")
                      .buildSink<ly::SizeRollSink>("test_size_roll/test.log", 1024 * 1024)
                      .build();
    for (int i = 0; i < 100000; ++i)
    {
        logger->debug("%s\n", "大小滚动文件输出器测试");
    }
}

void test_timeRollSink()
{
    auto logger = ly::LocalBuilder()
                      .buildName("test_logger")
                      .buildSink<ly::TimeRollSink>("test_time_roll/test.log", 3)
                      .build();
    for (int i = 0; i < 15; ++i)
    {
        logger->debug("%s\n", "时间滚动文件输出器测试");
        sleep(1);
    }
}

void test_level()
{
    auto logger = ly::LocalBuilder()
                      .buildName("test_logger")
                      .buildSink<ly::StdoutSink>()
                      .buildLimitLevel(ly::LogLevel::Level::warning)
                      .build();
    logger->debug("限制输出等级测试\n");
    logger->info("限制输出等级测试\n");
    logger->warning("限制输出等级测试\n");
    logger->error("限制输出等级测试\n");
    logger->fatal("限制输出等级测试\n");
}

void test_async1()
{
    size_t total = 10000000;
    size_t count_thread = 5;
    size_t count_message = total / count_thread;
    auto start_time = std::chrono::high_resolution_clock::now();
    std::vector<std::thread> threads;
    auto logger = ly::LocalBuilder()
                      .buildName("test_logger")
                      .buildSink<ly::SizeRollSink>("test_size_roll/test.log", 1024 * 1024 * 1024)
                      .buildType(ly::Logger::Type::async)
                      .build();
    for (size_t i = 0; i < count_thread; ++i)
    {
        threads.emplace_back(std::thread([&]()
                                         {
            for (size_t j = 0; j < count_message; ++j) {
                logger->debug("异步日志输出测试\n");
            } }));
    }

    for (auto &t : threads)
        t.join();

    auto end_time = std::chrono::high_resolution_clock::now();

    std::chrono::duration<double> elapsed = end_time - start_time;
    std::cout << elapsed.count() << " seconds " << total << " messages" << std::endl;
}

void test_async2()
{
    size_t total = 10000000;
    size_t count_thread = 5;
    size_t count_message = total / count_thread;
    auto start_time = std::chrono::high_resolution_clock::now();
    std::vector<std::thread> threads;

    for (size_t i = 0; i < count_thread; ++i)
    {
        threads.emplace_back(std::thread([&]()
                                         {
                auto logger = ly::LocalBuilder()
        .buildName("test_logger")
        .buildSink<ly::SizeRollSink>("test_size_roll/test.log", 1024 * 1024 * 1024)
        .buildType(ly::Logger::Type::async)
        .build();
            for (size_t j = 0; j < count_message; ++j) {
                logger->debug("异步日志输出测试\n");
            } }));
    }

    for (auto &t : threads)
        t.join();

    auto end_time = std::chrono::high_resolution_clock::now();

    std::chrono::duration<double> elapsed = end_time - start_time;
    std::cout << elapsed.count() << " seconds " << total << " messages" << std::endl;
}

void test_manager()
{
    auto logger = ly::LocalBuilder()
        .buildName("test_logger")
        .buildSink<ly::StdoutSink>()
        .buildType(ly::Logger::Type::async)
        .build();
    fdebug("日志器管理者测试\n");
    ly::LogManager::getInstance().addLogger("test_logger", logger);
    ly::LogManager::getInstance().getLogger("test_logger")->debug("测试测试\n");
}

int main()
{
    // test_basic();
    // test_fileSink();
    // test_sizeRollSink();
    // test_timeRollSink();
    // test_level();
    // test_async1();
    // test_async2();
    test_manager();
    return 0;
}